import json
import logging

import time
from binance.websocket.um_futures.websocket_client import UMFuturesWebsocketClient

from dao.influxdb_connection_factory import write_klines_to_influxdb, InfluxDBManager
from mq.sender import RabbitMQClient


def message_handler(message, data):
    """
    处理K线数据
    :param message:
    :param data:
    :return:
    """
    # 打印原始数据
    print(data)
    print("-------------------------------------------------")
    try:
        # 尝试将JSON字符串解析为字典
        data = json.loads(data)
        # 检查data是否包含"ping"字符串
        if data == "ping":
            my_client.ping()
        elif "e" in data and data["e"] == "kline":
            # 处理K线数据
            handle_kline_data(data)
        else:
            # 处理其他类型的数据
            handle_other_data(data)
    except json.JSONDecodeError:
        # 如果解析失败，打印错误信息并返回
        print("Received data is not a valid JSON string.")
        return


# 初始化数据库管理器
db_manager = InfluxDBManager()


def handle_kline_data(kline_data):
    # 提取K线数据的关键信息
    event_type = kline_data.get("e")
    event_time = kline_data.get("E")
    symbol = kline_data["k"].get("s")
    open_time = kline_data["k"].get("t")
    close_time = kline_data["k"].get("T")
    open_price = kline_data["k"].get("o")
    close_price = kline_data["k"].get("c")
    isClosed = kline_data["k"].get("x")
    NumberOfTrades = kline_data["k"].get("n")  # 表示这根K线内的成交次数
    Volume = kline_data["k"].get("v")  # 表示这根K线内的总成交量
    QuoteAssetVolume = kline_data["k"].get("q")  # 表示这根K线内的总成交金额
    WeightedVolume = kline_data["k"].get("V")  # 表示按成交量加权的成交量
    WeightedQuoteAssetVolume = kline_data["k"].get("Q")  # 表示按成交金额加权的成交额

    # 打印K线数据的摘要信息
    print(f"Event Type: {event_type}")
    print(f"Event Time: {event_time}")
    print(f"Symbol: {symbol}")
    print(f"Open Time: {open_time}")
    print(f"Close Time: {close_time}")
    print(f"Open Price: {open_price}")
    print(f"Close Price: {close_price}")
    print(f"IsClosed?: {isClosed}")

    # Convert open_time to nanoseconds and print it
    timestamp_ns = open_time * 1_000_000
    print(f"Timestamp (ns): {timestamp_ns}")

    write_klines_to_influxdb([kline_data], db_manager)
    client = RabbitMQClient()
    try:
        client.send_message(create_kline_str(kline_data))
    finally:
        client.close_connection()

    logging.info(f"Kline data has been written to InfluxDB.")
    print("----------------------done---------------------------")


def create_kline_str(kline):
    """
    创建一个Point对象，用于存储K线数据
    :param kline: K线数据
    :return: Point对象
    """
    o = float(kline["k"]["o"])
    c = float(kline["k"]["c"])
    h = float(kline["k"]["h"])
    l = float(kline["k"]["l"])
    v = float(kline["k"]["v"])
    t = int(kline["k"]["t"])
    s = kline["k"]["s"]
    i = kline["k"]["i"]
    obj = {
        's': s,
        'i': i,
        'o': o,
        'c': c,
        'h': h,
        'l': l,
        'v': v,
        't': t
    }
    return json.dumps(obj)


def handle_other_data(other_data):
    # 处理非K线数据的逻辑
    print("Handling other data types...")

    # 根据实际需求处理不同类型的数据


stream_url = 'wss://fstream.binancefuture.com'
is_combined = False
symbols = ["btcusdt", "ethusdt", "dogeusdt"]
my_client = UMFuturesWebsocketClient(on_message=message_handler,
                                     stream_url=stream_url,
                                     is_combined=is_combined)
for symbol in symbols:
    my_client.kline(symbol=symbol, interval="1m")
    time.sleep(1)
    my_client.kline(symbol=symbol, interval="3m")
    time.sleep(1)
    my_client.kline(symbol=symbol, interval="5m")
    time.sleep(1)
    my_client.kline(symbol=symbol, interval="15m")
    time.sleep(1)
    my_client.kline(symbol=symbol, interval="30m")
    time.sleep(1)
    my_client.kline(symbol=symbol, interval="1d")
    time.sleep(1)
